from dicRead import dicRead
  
def pivot(fname, noOfPivots):
    
    d = dicRead(fname)
    isUnbounded = False
    (m_by_n, basicIndices, nonbasicIndices, bVec, aMat, cVec ) = d
    #print 'From file ', m_by_n, basicIndices, nonbasicIndices, bVec, cVec, aMat
    print 'From file ', cVec
    if noOfPivots > 1:
        fileNameStep = fname.split('.')[0] + '.step'+str(noOfPivots)+'_output'
    else:
        fileNameStep = fname + '.step'+str(noOfPivots)+'_output'
    fo = open(fileNameStep, 'w')
    
    enteringArrIdx = 0
    for i, x in enumerate(cVec):
        if i == 0:
            continue
        if x > 0:
            enteringArrIdx = i
            break
    #print 'Entering x%d' % nonbasicIndices[enteringArrIdx-1], ' with %d' % (enteringArrIdx-1)
    #fo.write('%d\n'%nonbasicIndices[enteringArrIdx-1])
    coeff = 0
    ii = 0
    unbounded = True
    for i, x in enumerate(bVec):
        #print i, x, aMat[i][enteringArrIdx-1]
        if x != 0:        
            if (aMat[i][enteringArrIdx-1] < 0 and aMat[i][enteringArrIdx-1]/x < coeff):
                coeff = aMat[i][enteringArrIdx-1]/x
                ii = i
                unbounded = False
        else:
            if (aMat[i][enteringArrIdx-1] < 0):
                ii = i
                unbounded = False
    if (unbounded):
        print 'Unbounded'
        isUnbounded = True
    
    if(not isUnbounded):
        # lets swap basic variable with matrix index
        #print "swapping row %d" % basicIndices[ii],"of basic variable index value with column index %d "%nonbasicIndices[enteringArrIdx-1],"of non basic"
        tempIdx = basicIndices[ii]
        basicIndices[ii] = nonbasicIndices[enteringArrIdx-1]
        nonbasicIndices[enteringArrIdx-1] = tempIdx
        coeffTemp = -aMat[ii][enteringArrIdx-1]
        #print "Coefficient %f "%coeffTemp
        aMat[ii][enteringArrIdx-1] = -1.0 #better to use sign function
        #print "Now dividing bVec and aMat on row %d"%ii, "with %f"%coeffTemp
        bVec[ii] = bVec[ii]/coeffTemp
        for i, rowCoeTemp in enumerate(aMat[ii]):
            aMat[ii][i] = aMat[ii][i]/coeffTemp
            #print "New coefficient is %f "%aMat[ii][i]
        
        for rowi in range(len(aMat)):
            #print "index %d " % rowi , "values %f"% aMat[rowi][enteringArrIdx-1]
            coefRow = aMat[rowi][enteringArrIdx-1] #/coeffTemp        
            if rowi != ii:
                #print "row coefficient %f"%coefRow
                aMat[rowi][enteringArrIdx-1] = 0.0
                for lcol,v in enumerate(aMat[rowi]):
                    aMat[rowi][lcol] = aMat[rowi][lcol] + aMat[ii][lcol]*coefRow
                bVec[rowi] = bVec[rowi]+ bVec[ii]*coefRow
        
        cVec[0] = bVec[ii]*cVec[enteringArrIdx]+cVec[0]
        
        for lcol in range(len(nonbasicIndices)):
            if lcol+1 != enteringArrIdx :
                cVec[lcol+1] = cVec[lcol+1] + cVec[enteringArrIdx]*aMat[ii][lcol]
        
        cVec[enteringArrIdx] = cVec[enteringArrIdx]*aMat[ii][enteringArrIdx-1]
                        
        #print 'After pivoting ', m_by_n, basicIndices, nonbasicIndices, bVec, cVec, aMat
        print 'No Of Pivots', noOfPivots

        fo.write(' '.join(map(str,m_by_n)))
        fo.write('\n')
        fo.write(' '.join(map(str,basicIndices)))
        fo.write('\n')
        fo.write(' '.join(map(str,nonbasicIndices)))
        fo.write('\n')
        fo.write(' '.join(map(str,bVec)))
        
        for rowline in aMat:
            fo.write('\n')
            fo.write(' '.join(map(str,rowline)))
        fo.write('\n')
        fo.write(' '.join(map(str,cVec)))
        fo.close()
        
        for pvtCnt in range(1, len(cVec)):
            if cVec[pvtCnt] > 0:
                pivot(fileNameStep, noOfPivots+1)
            else:
                fo2 = open(fname.split('.')[0]+'.out', 'w')
                fo2.write(str(cVec[0]))                
                fo2.write('\n')
                fo2.write(str(noOfPivots))
                fo2.close()
                    
        print 'm_by_n, basicIndices, nonbasicIndices, bVec, aMat, cVec'
        
        tmpCvec = cVec[1:]
        tmpVec = [val1 for val1 in tmpCvec if val1 > 0]
        if len(tmpVec) == 0: 
            exit(0)

if __name__ == '__main__':
    
    fname = 'assignmentParts/part1.dict'
    pivot(fname, 1)